<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.14"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>LogDevice API: facebook::logdevice::Reader Class Reference</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="search/search.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="search/searchdata.js"></script>
<script type="text/javascript" src="search/search.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
 <tbody>
 <tr style="height: 56px;">
  <td id="projectalign" style="padding-left: 0.5em;">
   <div id="projectname">LogDevice API
   </div>
  </td>
 </tr>
 </tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.14 -->
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
var searchBox = new SearchBox("searchBox", "search",false,'Search');
/* @license-end */
</script>
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&amp;dn=gpl-2.0.txt GPL-v2 */
$(function() {
  initMenu('',true,false,'search.php','Search');
  $(document).ready(function() { init_search(); });
});
/* @license-end */</script>
<div id="main-nav"></div>
<!-- window showing the filter options -->
<div id="MSearchSelectWindow"
     onmouseover="return searchBox.OnSearchSelectShow()"
     onmouseout="return searchBox.OnSearchSelectHide()"
     onkeydown="return searchBox.OnSearchSelectKey(event)">
</div>

<!-- iframe showing the search results (closed by default) -->
<div id="MSearchResultsWindow">
<iframe src="javascript:void(0)" frameborder="0" 
        name="MSearchResults" id="MSearchResults">
</iframe>
</div>

<div id="nav-path" class="navpath">
  <ul>
<li class="navelem"><a class="el" href="namespacefacebook.html">facebook</a></li><li class="navelem"><b>logdevice</b></li><li class="navelem"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html">Reader</a></li>  </ul>
</div>
</div><!-- top -->
<div class="header">
  <div class="summary">
<a href="#pub-methods">Public Member Functions</a> &#124;
<a href="#pub-static-methods">Static Public Member Functions</a> &#124;
<a href="#pub-attribs">Public Attributes</a> &#124;
<a href="classfacebook_1_1logdevice_1_1_reader-members.html">List of all members</a>  </div>
  <div class="headertitle">
<div class="title">facebook::logdevice::Reader Class Reference<span class="mlabels"><span class="mlabel">abstract</span></span></div>  </div>
</div><!--header-->
<div class="contents">
<table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-methods"></a>
Public Member Functions</h2></td></tr>
<tr class="memitem:a211ad73ea203bf37a65745fe37f63cd1"><td class="memItemLeft" align="right" valign="top">virtual int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a211ad73ea203bf37a65745fe37f63cd1">startReading</a> (logid_t log_id, lsn_t from, lsn_t until=LSN_MAX, const ReadStreamAttributes *attrs=nullptr)=0</td></tr>
<tr class="separator:a211ad73ea203bf37a65745fe37f63cd1"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a7c5403cffbef361843ebb1344e44e716"><td class="memItemLeft" align="right" valign="top">virtual int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a7c5403cffbef361843ebb1344e44e716">stopReading</a> (logid_t log_id)=0</td></tr>
<tr class="separator:a7c5403cffbef361843ebb1344e44e716"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ab7e1afbc25ffe48b1e28f286bef85405"><td class="memItemLeft" align="right" valign="top">virtual bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#ab7e1afbc25ffe48b1e28f286bef85405">isReading</a> (logid_t log_id) const =0</td></tr>
<tr class="separator:ab7e1afbc25ffe48b1e28f286bef85405"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a1952c5b3d315903c8921e2128919dffa"><td class="memItemLeft" align="right" valign="top">virtual bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a1952c5b3d315903c8921e2128919dffa">isReadingAny</a> () const =0</td></tr>
<tr class="separator:a1952c5b3d315903c8921e2128919dffa"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a7fb6f4b893781cea92e959e4626c909b"><td class="memItemLeft" align="right" valign="top">virtual int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a7fb6f4b893781cea92e959e4626c909b">setTimeout</a> (std::chrono::milliseconds timeout)=0</td></tr>
<tr class="separator:a7fb6f4b893781cea92e959e4626c909b"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:abf34b34cad9917ddf748c2dbd2b325da"><td class="memItemLeft" align="right" valign="top">virtual ssize_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#abf34b34cad9917ddf748c2dbd2b325da">read</a> (size_t nrecords, std::vector&lt; std::unique_ptr&lt; DataRecord &gt; &gt; *data_out, GapRecord *gap_out)=0</td></tr>
<tr class="separator:abf34b34cad9917ddf748c2dbd2b325da"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a7ef97dd78f6f5c5da4200c6cdfd90d63"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a7ef97dd78f6f5c5da4200c6cdfd90d63">waitOnlyWhenNoData</a> ()=0</td></tr>
<tr class="separator:a7ef97dd78f6f5c5da4200c6cdfd90d63"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:af1812e18565f35607e5111a053bc6edf"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#af1812e18565f35607e5111a053bc6edf">withoutPayload</a> ()=0</td></tr>
<tr class="separator:af1812e18565f35607e5111a053bc6edf"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a71fcd2eda3b543ab4190d3c6c69c39a6"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a71fcd2eda3b543ab4190d3c6c69c39a6">forceNoSingleCopyDelivery</a> ()=0</td></tr>
<tr class="separator:a71fcd2eda3b543ab4190d3c6c69c39a6"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a016857a5ec3456b6ef04fc01805510c5"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a016857a5ec3456b6ef04fc01805510c5">includeByteOffset</a> ()=0</td></tr>
<tr class="separator:a016857a5ec3456b6ef04fc01805510c5"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a02ec782bdf411227da857eec6c88749f"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a02ec782bdf411227da857eec6c88749f">doNotSkipPartiallyTrimmedSections</a> ()=0</td></tr>
<tr class="separator:a02ec782bdf411227da857eec6c88749f"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a33ec99605bc4516d473f0a449ae319cf"><td class="memItemLeft" align="right" valign="top">virtual int&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a33ec99605bc4516d473f0a449ae319cf">isConnectionHealthy</a> (logid_t) const =0</td></tr>
<tr class="separator:a33ec99605bc4516d473f0a449ae319cf"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ab1c42c7d423374e6fd5072d686d6d557"><td class="memItemLeft" align="right" valign="top">virtual void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#ab1c42c7d423374e6fd5072d686d6d557">doNotDecodeBufferedWrites</a> ()=0</td></tr>
<tr class="separator:ab1c42c7d423374e6fd5072d686d6d557"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:a489977cdc984156ff8133416a6fae392"><td class="memItemLeft" align="right" valign="top">virtual&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a489977cdc984156ff8133416a6fae392">~Reader</a> ()</td></tr>
<tr class="separator:a489977cdc984156ff8133416a6fae392"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-static-methods"></a>
Static Public Member Functions</h2></td></tr>
<tr class="memitem:ab023b1f6d8a38bcf5bf04609e7a4065b"><td class="memItemLeft" align="right" valign="top">static lsn_t&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#ab023b1f6d8a38bcf5bf04609e7a4065b">nextFromLsnWhenStuck</a> (lsn_t stuck_lsn=LSN_INVALID, lsn_t tail_lsn=LSN_INVALID)</td></tr>
<tr class="separator:ab023b1f6d8a38bcf5bf04609e7a4065b"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table><table class="memberdecls">
<tr class="heading"><td colspan="2"><h2 class="groupheader"><a name="pub-attribs"></a>
Public Attributes</h2></td></tr>
<tr class="memitem:ae1464bd8d2cbbfd4955ba36ca561366f"><td class="memItemLeft" align="right" valign="top"><a id="ae1464bd8d2cbbfd4955ba36ca561366f"></a>
const std::chrono::milliseconds&#160;</td><td class="memItemRight" valign="bottom"><b>MAX_TIMEOUT</b> {(1LL&lt;&lt;31) - 1}</td></tr>
<tr class="separator:ae1464bd8d2cbbfd4955ba36ca561366f"><td class="memSeparator" colspan="2">&#160;</td></tr>
</table>
<h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
<a id="a489977cdc984156ff8133416a6fae392"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a489977cdc984156ff8133416a6fae392">&#9670;&nbsp;</a></span>~Reader()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual facebook::logdevice::Reader::~Reader </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">inline</span><span class="mlabel">virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>Note that, unless all reading is stopped prior to destruction, the destructor may block for some time while all reading gets stopped. This will typically finish quickly in applications but it does involve interthread communication for each log. </p>

</div>
</div>
<h2 class="groupheader">Member Function Documentation</h2>
<a id="ab1c42c7d423374e6fd5072d686d6d557"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ab1c42c7d423374e6fd5072d686d6d557">&#9670;&nbsp;</a></span>doNotDecodeBufferedWrites()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual void facebook::logdevice::Reader::doNotDecodeBufferedWrites </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>Instructs the <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html">Reader</a> instance to pass through blobs created by BufferedWriter.</p>
<p>By default (if this method is not called), <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html">Reader</a> automatically decodes blobs written by BufferedWriter and yields original records as passed to BufferedWriter::append(). If this method is called, BufferedWriteDecoder can be used to decode the blobs. </p>

</div>
</div>
<a id="a02ec782bdf411227da857eec6c88749f"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a02ec782bdf411227da857eec6c88749f">&#9670;&nbsp;</a></span>doNotSkipPartiallyTrimmedSections()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual void facebook::logdevice::Reader::doNotSkipPartiallyTrimmedSections </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>If called, when reading a section of the log that has been partially trimmed, the reader will deliver whatever records are still available, which (because of LogDevice's distributed and nondeterministic nature) results in an interleaved stream of records and TRIM gaps, which is undesirable in some cases.</p>
<p>The default behaviour is to deliver a large trim gap for the entire section.</p>
<p>See doc/partially-trimmed.md for a detailed explanation. </p>

</div>
</div>
<a id="a71fcd2eda3b543ab4190d3c6c69c39a6"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a71fcd2eda3b543ab4190d3c6c69c39a6">&#9670;&nbsp;</a></span>forceNoSingleCopyDelivery()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual void facebook::logdevice::Reader::forceNoSingleCopyDelivery </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>If called, disable the single copy delivery optimization even if the log is configured to support it. Each data record will be sent by all storage nodes that have a copy instead of exactly one. This greatly increases read availability at the cost of higher network bandwith and cpu usage.</p>
<p>Only affects subsequent <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a211ad73ea203bf37a65745fe37f63cd1">startReading()</a> calls. </p>

</div>
</div>
<a id="a016857a5ec3456b6ef04fc01805510c5"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a016857a5ec3456b6ef04fc01805510c5">&#9670;&nbsp;</a></span>includeByteOffset()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual void facebook::logdevice::Reader::includeByteOffset </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>If called, data records read by this <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html">Reader</a> will start including approximate amount of data written to given log up to current record once it become available to <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html">Reader</a>.</p>
<p>The value itself stored in DataRecord::attrs::byte_offset. Set as BYTE_OFFSET_INVALID if unavailable to <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html">Reader</a> yet.</p>
<p>Only affects subsequent <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a211ad73ea203bf37a65745fe37f63cd1">startReading()</a> calls. </p>

</div>
</div>
<a id="a33ec99605bc4516d473f0a449ae319cf"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a33ec99605bc4516d473f0a449ae319cf">&#9670;&nbsp;</a></span>isConnectionHealthy()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual int facebook::logdevice::Reader::isConnectionHealthy </td>
          <td>(</td>
          <td class="paramtype">logid_t&#160;</td>
          <td class="paramname"></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>Checks if the connection to the LogDevice cluster for a log appears healthy. When a <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#abf34b34cad9917ddf748c2dbd2b325da">read()</a> call times out, this can be used to make an informed guess whether this is because there is no data or because there a service interruption.</p>
<p>NOTE: this is not 100% accurate but will expose common issues like losing network connectivity.</p>
<dl class="section return"><dt>Returns</dt><dd>On success, returns 1 if the connection appears healthy or 0 if there are issues talking to the cluster. On error returns -1 and sets err to NOTFOUND (not reading given log). </dd></dl>

</div>
</div>
<a id="ab7e1afbc25ffe48b1e28f286bef85405"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ab7e1afbc25ffe48b1e28f286bef85405">&#9670;&nbsp;</a></span>isReading()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual bool facebook::logdevice::Reader::isReading </td>
          <td>(</td>
          <td class="paramtype">logid_t&#160;</td>
          <td class="paramname"><em>log_id</em></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>Checks if a log is being read. Can be used to find out if the end of the log was reached (for a log that was being read). </p>

</div>
</div>
<a id="a1952c5b3d315903c8921e2128919dffa"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a1952c5b3d315903c8921e2128919dffa">&#9670;&nbsp;</a></span>isReadingAny()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual bool facebook::logdevice::Reader::isReadingAny </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td> const</td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>Checks if any log is being read. Can be used to find out if the end was reached for <em>all</em> logs that were being read. </p>

</div>
</div>
<a id="ab023b1f6d8a38bcf5bf04609e7a4065b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#ab023b1f6d8a38bcf5bf04609e7a4065b">&#9670;&nbsp;</a></span>nextFromLsnWhenStuck()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">static lsn_t facebook::logdevice::Reader::nextFromLsnWhenStuck </td>
          <td>(</td>
          <td class="paramtype">lsn_t&#160;</td>
          <td class="paramname"><em>stuck_lsn</em> = <code>LSN_INVALID</code>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">lsn_t&#160;</td>
          <td class="paramname"><em>tail_lsn</em> = <code>LSN_INVALID</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">static</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>Get next lowest recommended LSN to read from when servers appear stuck.</p>
<p>To force progress when stuck at <code>stuck_lsn</code>, call <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a7c5403cffbef361843ebb1344e44e716">stopReading()</a>, then call <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a211ad73ea203bf37a65745fe37f63cd1">startReading()</a> from nextFromLsnWhenStuck(stuck_lsn).</p>
<p>NOTE: Forcing progress is likely to miss some records between stuck_lsn and nextFromLsnWhenStuck(stuck_lsn). The records will become available eventually (once server-side issues have been resolved), but the only way to read them is to re-read the section from stuck_lsn to nextFromLsnWhenStuck(stuck_lsn) later.</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">stuck_lsn</td><td>LSN at which the reader got stuck; that is, the last LSN the reader tried to read or managed to read (+-1 does not affect the output of this function). </td></tr>
    <tr><td class="paramname">tail_lsn</td><td>Tail LSN, if known, as returned by <a class="el" href="classfacebook_1_1logdevice_1_1_client.html#ae5854411762db40e48ba2e74142297c2">Client::getTailLSN()</a> or <a class="el" href="classfacebook_1_1logdevice_1_1_client.html#a1e0c38ddae87c659ff68bbea760f020b">Client::findTime()</a>. </td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Recommended LSN to use as <code>from_lsn</code> in startRead() to make progress, no less than <code>stuck_lsn</code>. </dd></dl>

</div>
</div>
<a id="abf34b34cad9917ddf748c2dbd2b325da"></a>
<h2 class="memtitle"><span class="permalink"><a href="#abf34b34cad9917ddf748c2dbd2b325da">&#9670;&nbsp;</a></span>read()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual ssize_t facebook::logdevice::Reader::read </td>
          <td>(</td>
          <td class="paramtype">size_t&#160;</td>
          <td class="paramname"><em>nrecords</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">std::vector&lt; std::unique_ptr&lt; DataRecord &gt; &gt; *&#160;</td>
          <td class="paramname"><em>data_out</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">GapRecord *&#160;</td>
          <td class="paramname"><em>gap_out</em>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>Attempts to read a batch of records.</p>
<p>The call either delivers 0 or more (up to <code>nrecords</code>) data records, or one gap record.</p>
<p>The call returns when any of this is true:</p><ul>
<li><code>nrecords</code> records have been delivered</li>
<li>there are no more records to deliver at the moment and the timeout specified by <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a7fb6f4b893781cea92e959e4626c909b">setTimeout()</a> has been reached</li>
<li>there are no more records to deliver at the moment and <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a7ef97dd78f6f5c5da4200c6cdfd90d63">waitOnlyWhenNoData()</a> was called</li>
<li>a gap in sequence numbers is encountered</li>
<li><code>until</code> LSN for some log was reached</li>
<li>not reading any logs, possibly because the ends of all logs have been reached (returns 0 quickly)</li>
</ul>
<p>Note that even in the case of an infinite timeout, the call may deliver less than <code>nrecords</code> data records when a gap is encountered. The next call to <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#abf34b34cad9917ddf748c2dbd2b325da">read()</a> will deliver the gap.</p>
<p>Waiting will not be interrupted if a signal is delivered to the thread.</p>
<p>Example usage: std::vector&lt;std::unique_ptr&lt;DataRecord&gt; &gt; records; GapRecord gap; ssize_t nread = reader-&gt;read(100, &amp;records, &amp;gap); if (nread &gt;= 0) { for (int i=0; i&lt;nread; ++i) { // process *records[i] } } else { assert(err == E::GAP); // process gap }</p>
<dl class="params"><dt>Parameters</dt><dd>
  <table class="params">
    <tr><td class="paramname">nrecords</td><td>limit on number of records to return data_out pointer to vector to append data records to gap_out pointer to a single GapRecord instance, populated when there is a gap in sequence numbers</td></tr>
  </table>
  </dd>
</dl>
<dl class="section return"><dt>Returns</dt><dd>Returns the number of records delivered (between 0 and <code>nrecords</code>), or -1 if there was a gap. If &gt;= 0, that many data records were appended to the vector. If -1 then logdevice::err is set to E::GAP, and *gap_out is filled with information about the gap. </dd></dl>

</div>
</div>
<a id="a7fb6f4b893781cea92e959e4626c909b"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a7fb6f4b893781cea92e959e4626c909b">&#9670;&nbsp;</a></span>setTimeout()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual int facebook::logdevice::Reader::setTimeout </td>
          <td>(</td>
          <td class="paramtype">std::chrono::milliseconds&#160;</td>
          <td class="paramname"><em>timeout</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>Sets the limit on how long <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#abf34b34cad9917ddf748c2dbd2b325da">read()</a> calls may wait for records to become available. A timeout of -1 means no limit (infinite timeout). A timeout of 0 means no waiting (nonblocking reads).</p>
<p>Default is no limit.</p>
<p>The maximum timeout is 2^31-1 milliseconds (about 24 days). If a timeout larger than that is passed in, it will be capped.</p>
<dl class="section return"><dt>Returns</dt><dd>0 on success, -1 if the parameter was invalid </dd></dl>

</div>
</div>
<a id="a211ad73ea203bf37a65745fe37f63cd1"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a211ad73ea203bf37a65745fe37f63cd1">&#9670;&nbsp;</a></span>startReading()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual int facebook::logdevice::Reader::startReading </td>
          <td>(</td>
          <td class="paramtype">logid_t&#160;</td>
          <td class="paramname"><em>log_id</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">lsn_t&#160;</td>
          <td class="paramname"><em>from</em>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">lsn_t&#160;</td>
          <td class="paramname"><em>until</em> = <code>LSN_MAX</code>, </td>
        </tr>
        <tr>
          <td class="paramkey"></td>
          <td></td>
          <td class="paramtype">const ReadStreamAttributes *&#160;</td>
          <td class="paramname"><em>attrs</em> = <code>nullptr</code>&#160;</td>
        </tr>
        <tr>
          <td></td>
          <td>)</td>
          <td></td><td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>Start reading a log. Similar to <a class="el" href="classfacebook_1_1logdevice_1_1_async_reader.html#a13331e00d2b9fd60c3d956927dd3cefc">AsyncReader::startReading()</a>.</p>
<p>Any one log can only be read once by a single <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html">Reader</a>. If this method is called for the same log multiple times, it restarts reading, optionally at a different point.</p>
<dl class="section return"><dt>Returns</dt><dd>On success, returns 0. On failure, -1 is returned and logdevice::err is set to: NOBUFS if request could not be enqueued because a buffer space limit was reached INVALID_PARAM if from &gt; until or the record callback was not specified. NOTFOUND if the log doesn't exist SHUTDOWN the <a class="el" href="classfacebook_1_1logdevice_1_1_client.html">logdevice::Client</a> instance was destroyedA. INTERNAL an internal error has been detected, check logs. TOOMANY exceeded limit on number of logs that had been specified the <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html">Reader</a> was created. </dd></dl>

</div>
</div>
<a id="a7c5403cffbef361843ebb1344e44e716"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a7c5403cffbef361843ebb1344e44e716">&#9670;&nbsp;</a></span>stopReading()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual int facebook::logdevice::Reader::stopReading </td>
          <td>(</td>
          <td class="paramtype">logid_t&#160;</td>
          <td class="paramname"><em>log_id</em></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>Stop reading a log.</p>
<dl class="section return"><dt>Returns</dt><dd>On success, returns 0. On failure, -1 is returned and logdevice::err is set to: [any of the error codes from <a class="el" href="classfacebook_1_1logdevice_1_1_async_reader.html#a7e26fd1ce23777a8af17922a3005f1ef">AsyncReader::stopReading()</a>] NOTFOUND log is not being read </dd></dl>

</div>
</div>
<a id="a7ef97dd78f6f5c5da4200c6cdfd90d63"></a>
<h2 class="memtitle"><span class="permalink"><a href="#a7ef97dd78f6f5c5da4200c6cdfd90d63">&#9670;&nbsp;</a></span>waitOnlyWhenNoData()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual void facebook::logdevice::Reader::waitOnlyWhenNoData </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>If called, whenever <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#abf34b34cad9917ddf748c2dbd2b325da">read()</a> can return some records but not the number requested by the caller, it will return the records instead of waiting for more.</p>
<p>Example:</p><ul>
<li>Caller calls read(100, ...) asking for 100 data records.</li>
<li>Only 20 records are immediately available.</li>
<li>By default, <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#abf34b34cad9917ddf748c2dbd2b325da">read()</a> would wait until 80 more records arrive or the timeout expires. This makes sense for callers that can benefit from reading and processing batches of data records.</li>
<li>If this method was called before <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#abf34b34cad9917ddf748c2dbd2b325da">read()</a>, it would return the 20 records without waiting for more. This may make sense for cases where latency is more important. </li>
</ul>

</div>
</div>
<a id="af1812e18565f35607e5111a053bc6edf"></a>
<h2 class="memtitle"><span class="permalink"><a href="#af1812e18565f35607e5111a053bc6edf">&#9670;&nbsp;</a></span>withoutPayload()</h2>

<div class="memitem">
<div class="memproto">
<table class="mlabels">
  <tr>
  <td class="mlabels-left">
      <table class="memname">
        <tr>
          <td class="memname">virtual void facebook::logdevice::Reader::withoutPayload </td>
          <td>(</td>
          <td class="paramname"></td><td>)</td>
          <td></td>
        </tr>
      </table>
  </td>
  <td class="mlabels-right">
<span class="mlabels"><span class="mlabel">pure virtual</span></span>  </td>
  </tr>
</table>
</div><div class="memdoc">
<p>If called, data records read by this <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html">Reader</a> will not include payloads.</p>
<p>This makes reading more efficient when payloads are not needed (they won't be transmitted over the network).</p>
<p>Only affects subsequent <a class="el" href="classfacebook_1_1logdevice_1_1_reader.html#a211ad73ea203bf37a65745fe37f63cd1">startReading()</a> calls. </p>

</div>
</div>
<hr/>The documentation for this class was generated from the following file:<ul>
<li>/Users/chunma/fbsource/fbcode/logdevice/include/<a class="el" href="_reader_8h_source.html">Reader.h</a></li>
</ul>
</div><!-- contents -->
<!-- HTML footer for doxygen 1.8.14-->
<!-- start footer part -->
<hr class="footer"/><address class="footer">
<small>
LogDevic API v2.35
</small>
</address>
</body>
</html>
